﻿using CLROBS;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesertKharonIrcPlugin
{
    public enum RenderAlignment : int
    { 
        Horizontal = 0,
        Vertical = 1
    }

    public enum LoginPreset : int
    {
        Custom = 0,
        Twitch = 1
    }

    public class DesertKharonIrcPluginSettings
    {
        private static string _stringListSeparator = "}!# SLS *!{"; // GetStringList & SetStringList seem to be not working.
        public static string StringListSeparator
        {
            get { return _stringListSeparator; }
            set { _stringListSeparator = value; }
        }


        private XElement _config;

        public LoginPreset LoginPreset
        {
            get { return (LoginPreset)_config.GetInt("loginPreset", (int)LoginPreset.Twitch); }
            set { _config.SetFloat("loginPreset", (int)value); }
        }

        public string IrcServer
        {
            get { return _config.GetString("ircServer", "irc.twitch.tv"); }
            set { _config.SetString("ircServer", value); }
        }

        public int IrcServerPort
        {
            get { return _config.GetInt("ircServerPort", 6667); }
            set { _config.SetInt("ircServerPort", value); }
        }

        public string IrcServerChannelName
        {
            get { return _config.GetString("ircServerChannelName", ""); }
            set { _config.SetString("ircServerChannelName", value); }
        }

        public string BroadcasterNickName
        {
            get { return _config.GetString("broadcasterNickName", ""); }
            set { _config.SetString("broadcasterNickName", value); }
        }

        public string IrcServerNickName
        {
            get { return _config.GetString("ircServerNickName", String.Empty); }
            set { _config.SetString("ircServerNickName", value); }
        }

        public string IrcServerPassword
        {
            get { return _config.GetString("ircServerPassword", String.Empty); }
            set { _config.SetString("ircServerPassword", value); }
        }

        public int ObsDefinedWidth
        {
            get { return _config.Parent.GetInt("cx"); }
            set { _config.Parent.SetInt("cx", value); }
        }

        public int ObsDefinedHeight
        {
            get { return _config.Parent.GetInt("cy"); }
            set { _config.Parent.SetInt("cy", value); }
        }

        public RenderAlignment RenderAlignment
        {
            get 
            { 
                int renderAlignInt = _config.GetInt("renderAlignment", (int)RenderAlignment.Horizontal);
                if (renderAlignInt == (int)RenderAlignment.Horizontal)
                    return RenderAlignment.Horizontal;
                else
                    return RenderAlignment.Vertical;
            }
            set { _config.SetInt("renderAlignment", (int)value); }
        }

        public Font Font
        {
            get { return new Font(this.FontFamily, this.FontSize, this.FontStyle); }
            set 
            {
                this.FontFamily = value.FontFamily;
                this.FontStyle = value.Style;
                this.FontSize = value.Size;
            }
        }

        public FontFamily FontFamily
        {
            get { return new FontFamily(_config.GetString("fontFamily", "Arial")); }
            set { _config.SetString("fontFamily", value.Name); }
        }

        public FontStyle FontStyle
        {
            get { return (FontStyle)_config.GetInt("fontStyle", (int)FontStyle.Regular); }
            set { _config.SetInt("fontStyle", (int)value); }
        }

        public float FontSize
        {
            get { return Math.Max(6f, Math.Min(_config.GetFloat("fontSize", 12f), 200f)); }
            set { _config.SetFloat("fontSize", Math.Max(6f, Math.Min(value, 200f))); }
        }

        public Color FontColor
        {
            get { return Color.FromArgb(_config.GetColor("fontColor", Color.White.ToArgb())); }
            set { _config.SetColor("fontColor", value.ToArgb()); }
        }

        public bool TwitchColors
        {
            get { return _config.GetInt("twitchColors", 1) != 0; }
            set { _config.SetInt("twitchColors", value ? 1 : 0); }
        }

        public bool FontOutline
        {
            get { return _config.GetInt("fontOutline", 1) != 0; }
            set { _config.SetInt("fontOutline", value ? 1 : 0); }
        }

        public int FontOutlineThickness
        {
            get { return Math.Max(1, Math.Min(_config.GetInt("fontOutlineThickness", 2), 16)); }
            set { _config.SetInt("fontOutlineThickness", Math.Max(1, Math.Min(value, 16))); }
        }

        public Color FontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("fontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("fontOutlineColor", value.ToArgb()); }
        }
        public Color BackgroundColor
        {
            get { return Color.FromArgb(_config.GetColor("backgroundColor", Color.Transparent.ToArgb())); }
            set { _config.SetColor("backgroundColor", value.ToArgb()); }
        }
        public Color BroadcasterNicknameFontColor
        {
            get { return Color.FromArgb(_config.GetColor("broadcasterNicknameFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("broadcasterNicknameFontColor", value.ToArgb()); }
        }

        public bool DifferentBroadcasterNicknameOutline
        {
            get { return _config.GetInt("differentBroadcasterNicknameOutline", 0) != 0; }
            set { _config.SetInt("differentBroadcasterNicknameOutline", value ? 1 : 0); }
        }

        public Color BroadcasterNicknameFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("broadcasterNicknameFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("broadcasterNicknameFontOutlineColor", value.ToArgb()); }
        }

        public Color BroadcasterMessageFontColor
        {
            get { return Color.FromArgb(_config.GetColor("broadcasterMessageFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("broadcasterMessageFontColor", value.ToArgb()); }
        }

        public bool DifferentBroadcasterMessageOutline
        {
            get { return _config.GetInt("differentBroadcasterMessageOutline", 0) != 0; }
            set { _config.SetInt("differentBroadcasterMessageOutline", value ? 1 : 0); }
        }

        public Color BroadcasterMessageFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("broadcasterMessageFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("broadcasterMessageFontOutlineColor", value.ToArgb()); }
        }

        public Color ModeratorNicknameFontColor
        {
            get { return Color.FromArgb(_config.GetColor("moderatorNicknameFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("moderatorNicknameFontColor", value.ToArgb()); }
        }

        public bool DifferentModeratorNicknameOutline
        {
            get { return _config.GetInt("differentModeratorNicknameOutline", 0) != 0; }
            set { _config.SetInt("differentModeratorNicknameOutline", value ? 1 : 0); }
        }

        public Color ModeratorNicknameFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("moderatorNicknameFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("moderatorNicknameFontOutlineColor", value.ToArgb()); }
        }

        public Color ModeratorMessageFontColor
        {
            get { return Color.FromArgb(_config.GetColor("moderatorMessageFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("moderatorMessageFontColor", value.ToArgb()); }
        }

        public bool DifferentModeratorMessageOutline
        {
            get { return _config.GetInt("differentModeratorMessageOutline", 0) != 0; }
            set { _config.SetInt("differentModeratorMessageOutline", value ? 1 : 0); }
        }

        public Color ModeratorMessageFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("moderatorMessageFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("moderatorMessageFontOutlineColor", value.ToArgb()); }
        }

        public Color FriendNicknameFontColor
        {
            get { return Color.FromArgb(_config.GetColor("friendNicknameFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("friendNicknameFontColor", value.ToArgb()); }
        }

        public bool DifferentFriendNicknameOutline
        {
            get { return _config.GetInt("differentFriendNicknameOutline", 0) != 0; }
            set { _config.SetInt("differentFriendNicknameOutline", value ? 1 : 0); }
        }

        public Color FriendNicknameFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("friendNicknameFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("friendNicknameFontOutlineColor", value.ToArgb()); }
        }

        public Color FriendMessageFontColor
        {
            get { return Color.FromArgb(_config.GetColor("friendMessageFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("friendMessageFontColor", value.ToArgb()); }
        }

        public bool DifferentFriendMessageOutline
        {
            get { return _config.GetInt("differentFriendMessageOutline", 0) != 0; }
            set { _config.SetInt("differentFriendMessageOutline", value ? 1 : 0); }
        }

        public Color FriendMessageFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("friendMessageFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("friendMessageFontOutlineColor", value.ToArgb()); }
        }

        public Color FoeNicknameFontColor
        {
            get { return Color.FromArgb(_config.GetColor("foeNicknameFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("foeNicknameFontColor", value.ToArgb()); }
        }

        public bool DifferentFoeNicknameOutline
        {
            get { return _config.GetInt("differentFoeNicknameOutline", 0) != 0; }
            set { _config.SetInt("differentFoeNicknameOutline", value ? 1 : 0); }
        }

        public Color FoeNicknameFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("foeNicknameFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("foeNicknameFontOutlineColor", value.ToArgb()); }
        }

        public Color FoeMessageFontColor
        {
            get { return Color.FromArgb(_config.GetColor("foeMessageFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("foeMessageFontColor", value.ToArgb()); }
        }

        public bool DifferentFoeMessageOutline
        {
            get { return _config.GetInt("differentFoeMessageOutline", 0) != 0; }
            set { _config.SetInt("differentFoeMessageOutline", value ? 1 : 0); }
        }

        public Color FoeMessageFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("foeMessageFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("foeMessageFontOutlineColor", value.ToArgb()); }
        }

        public Color UserNicknameFontColor
        {
            get { return Color.FromArgb(_config.GetColor("userNicknameFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("userNicknameFontColor", value.ToArgb()); }
        }

        public bool DifferentUserNicknameOutline
        {
            get { return _config.GetInt("differentUserNicknameOutline", 0) != 0; }
            set { _config.SetInt("differentUserNicknameOutline", value ? 1 : 0); }
        }

        public Color UserNicknameFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("userNicknameFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("userNicknameFontOutlineColor", value.ToArgb()); }
        }

        public Color UserMessageFontColor
        {
            get { return Color.FromArgb(_config.GetColor("userMessageFontColor", Color.White.ToArgb())); }
            set { _config.SetColor("userMessageFontColor", value.ToArgb()); }
        }

        public bool DifferentUserMessageOutline
        {
            get { return _config.GetInt("differentUserMessageOutline", 0) != 0; }
            set { _config.SetInt("differentUserMessageOutline", value ? 1 : 0); }
        }

        public Color UserMessageFontOutlineColor
        {
            get { return Color.FromArgb(_config.GetColor("userMessageFontOutlineColor", Color.Black.ToArgb())); }
            set { _config.SetColor("userMessageFontOutlineColor", value.ToArgb()); }
        }

        public string NickNameFormat
        {
            get { return _config.GetString("nickNameFormat", "{time}{nick}:"); }
            set { _config.SetString("nickNameFormat", value); }
        }

        public string FollowupNickNameFormat
        {
            get { return _config.GetString("followupNickNameFormat", ">"); }
            set { _config.SetString("followupNickNameFormat", value); }
        }

        public string MessageFormat
        {
            get { return _config.GetString("messageFormat", "{msg}"); }
            set { _config.SetString("messageFormat", value); }
        }

        public string TimeFormat
        {
            get { return _config.GetString("timeFormat", "H:mm|"); }
            set { _config.SetString("timeFormat", value); }
        }

        public float MessageFadeOutAfterInSeconds
        {
            get { return Math.Max(0f, Math.Min(_config.GetFloat("messageFadeOutAfterInSeconds", 150f), 3600f)); }
            set { _config.SetFloat("messageFadeOutAfterInSeconds", Math.Max(0f, Math.Min(value, 3600f))); }
        }

        public float MessageFadeOutTimeInSeconds
        {
            get { return Math.Max(0.1f, Math.Min(_config.GetFloat("messageFadeOutTimeInSeconds", 2.5f), 10f)); }
            set { _config.SetFloat("messageFadeOutTimeInSeconds", Math.Max(0.1f, Math.Min(value, 10f))); }
        }

        // GetStringList & SetStringList seem to be not working.
        public List<string> ModeratorList
        {
            get 
            { 
                string moderatorListString = _config.GetString("moderatorList");
                if (!String.IsNullOrWhiteSpace(moderatorListString))
                {
                    string[] moderatorListArray = moderatorListString.Split(new string[] { _stringListSeparator }, StringSplitOptions.RemoveEmptyEntries);
                    if (moderatorListArray != null && moderatorListArray.Length > 0)
                        return moderatorListArray.ToList();
                }

                return new List<string>();
            }
            set { _config.SetString("moderatorList", value == null ? "" : String.Join(_stringListSeparator, value)); }
        }

        // GetStringList & SetStringList seem to be not working.
        public List<string> FriendList
        {
            get
            {
                string friendListString = _config.GetString("friendList");
                if (!String.IsNullOrWhiteSpace(friendListString))
                {
                    string[] friendListArray = friendListString.Split(new string[] { _stringListSeparator }, StringSplitOptions.RemoveEmptyEntries);
                    if (friendListArray != null && friendListArray.Length > 0)
                        return friendListArray.ToList();
                }

                return new List<string>();
            }
            set { _config.SetString("friendList", value == null ? "" : String.Join(_stringListSeparator, value)); }
        }

        // GetStringList & SetStringList seem to be not working.
        public List<string> FoeList
        {
            get
            {
                string foeListString = _config.GetString("foeList");
                if (!String.IsNullOrWhiteSpace(foeListString))
                {
                    string[] foeListArray = foeListString.Split(new string[] { _stringListSeparator }, StringSplitOptions.RemoveEmptyEntries);
                    if (foeListArray != null && foeListArray.Length > 0)
                        return foeListArray.ToList();
                }

                return new List<string>();
            }
            set { _config.SetString("foeList", value == null ? "" : String.Join(_stringListSeparator, value)); }
        }

        // GetStringList & SetStringList seem to be not working.
        public List<string> IgnoreList
        {
            get
            {
                string ignoreListString = _config.GetString("ignoreList");
                if (!String.IsNullOrWhiteSpace(ignoreListString))
                {
                    string[] ignoreListArray = ignoreListString.Split(new string[] { _stringListSeparator }, StringSplitOptions.RemoveEmptyEntries);
                    if (ignoreListArray != null && ignoreListArray.Length > 0)
                        return ignoreListArray.ToList();
                }

                return new List<string>();
            }
            set { _config.SetString("ignoreList", value == null ? "" : String.Join(_stringListSeparator, value)); }
        }

        public float Opacity
        {
            get { return Math.Max(0.0f, Math.Min(_config.GetFloat("opacity", 1.0f), 1.0f)); }
            set { _config.SetFloat("opacity", Math.Max(0.0f, Math.Min(value, 1.0f))); }
        }

        public bool ShowJoinsParts
        {
            get { return _config.GetInt("showJoinsParts", 0) == 1; }
            set { _config.SetInt("showJoinsParts", value ? 1 : 0); }
        }

        public DesertKharonIrcPluginSettings(XElement config)
        {
            _config = config;
        }

        public bool ParseTwitchEmotes
        {
            get { return _config.GetInt("parseTwitchEmotes", 0) == 1; }
            set { _config.SetInt("parseTwitchEmotes", value ? 1 : 0); }
        }

        
    }
}
